#ifndef SKYROAD_XML_IARCHIVE_H_
#define SKYROAD_XML_IARCHIVE_H_

#include <string>
#include <vector>
#include <boost/array.hpp>
#include <boost/lexical_cast.hpp>
#include <skyroad/archive/nvp.hpp>
#include <skyroad/detail/config.hpp>
#include <skyroad/util/convert_to.hpp>
#include <skyroad/archive/xmlprotocolparser.h>

 
SKYROAD_DECL bool xml_load_from_string(TiXmlElement& element,const CHAR* szCommand,int nLength );

class SKYROAD_DECL xml_iarchive
{
public:
    xml_iarchive(TiXmlElement& data,int version)
        :m_data(data), m_version(version)
    {

    }
    void get_com_id(WORD& comid)
    {
        WXmlParser_GetCommand(&m_data, comid );
    }

    void read(const std::string& key, std::string& s)
    {
        char st[1024] = {0};
        WXmlParser_GetFieldValue(&m_data,key.c_str(),st,1024);
        s = st; 
    }

    //     void write(const std::wstring& s)
    //     {
    //         m_data.append(unicode_to_native(s));
    //     }

    void read(const std::string& key, char& s) 
    {
        WXmlParser_GetFieldValue(&m_data,key.c_str(),&s,1);
    }

    void read(const std::string& key, int& s)
    {
        WXmlParser_GetFieldValue(&m_data,key.c_str(),s);
    }


    template <typename  T>
    void read(const std::string& key,std::vector<T>& a) 
    {

        TiXmlElement *pSubElement = m_data.FirstChildElement( key.c_str());
        while (pSubElement)
        {
            T t;
            xml_iarchive ia(*pSubElement,m_version);
            serialize(ia, t, m_version);
            a.push_back(t);
           pSubElement = pSubElement->NextSiblingElement( key.c_str());
        }
    }

    template <std::size_t N>
    void read(const std::string& key,boost::array<char, N>& a) 
    {
        std::string s(&a[0]);
        WXmlParser_GetFieldValue(&m_data,key.c_str(),s);
    }

    template <std::size_t N>
    void read(const std::string& key,boost::array<unsigned char, N>& a) 
    {
        std::string s((char*)&a[0],N);
        WXmlParser_GetFieldValue(&m_data,key.c_str(),s);
    }

    template <std::size_t N>
    void read(const std::string& key,boost::array<wchar_t, N>& a)
    {
        std::wstring s(&a[0]);
        WXmlParser_GetFieldValue(&m_data,key.c_str(),unicode_to_native(s));
    }

    template <typename T>
    void read(std::vector<T>& v)
    {
        for (int i = 0; i < v.size(); i++)
        {
            serialize(*this, v[i], m_version);
        }
    }

    template <typename Value>
    void read(const nvp<Value>& nv)
    {

        if (nv.first != NULL && nv.first[0] != '#')
        {
            read(&m_data,nv.first.c_str(),*nv.second);
        }
    }

private:
    TiXmlElement& m_data; 
    int m_version;
};


template <typename Value>
inline xml_iarchive& operator &(xml_iarchive& out, const nvp<Value>& nv)
{
    std::string str = nv.first;
    out.read(str,*nv.second);
    return out;
}

#endif